package com.qiaofang.applet.service.property.service.impl;

import com.google.common.collect.Lists;
import com.mongodb.client.result.UpdateResult;
import com.qiaofang.applet.common.base.MongoBaseService;
import com.qiaofang.applet.constants.UpDownFlagConstants;
import com.qiaofang.applet.service.other.domain.SynchronousData;
import com.qiaofang.applet.service.other.service.CityCompanyService;
import com.qiaofang.applet.service.other.service.CorporationService;
import com.qiaofang.applet.service.property.domain.Property;
import com.qiaofang.applet.service.property.domain.SyncDataErrorLog;
import com.qiaofang.applet.service.property.repository.SyncDataLogRepository;
import com.qiaofang.applet.service.property.service.SyncDataLogService;
import com.qiaofang.applet.service.property.service.dto.CountSynDataListDto;
import com.qiaofang.applet.service.property.service.dto.SyncDataLogQueryDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author QF2019
 */
@Slf4j
@Service
public class SyncDataLogServiceImpl extends MongoBaseService<SyncDataErrorLog, String> implements SyncDataLogService {

    public static final String SUCC_CODE = "1";

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private CityCompanyService cityCompanyService;

    @Autowired
    private CorporationService corporationService;

    private final SyncDataLogRepository repository;

    public SyncDataLogServiceImpl(SyncDataLogRepository repository) {
        super(repository);
        this.repository = repository;
    }

    @Override
    public Page<SyncDataErrorLog> findByParams(SyncDataLogQueryDto queryDto, Pageable pageable) {
        // 1、拼查询公共条件
        Query queryCriteria = createFindQuery(queryDto);

        // 2、在 queryCriteria基础上再拼每个查询特有的一些查询条件
        // 3、拼分页参数
        queryCriteria.with(pageable);

        // 4、查询记录条件
        long count = mongoTemplate.count(queryCriteria, SyncDataErrorLog.class);

        // 5、拼排序参数
        queryCriteria.with(Sort.by(Sort.Order.desc("id")));

        log.info("同步日志条数:{}", count);
        List<SyncDataErrorLog> content = new ArrayList<>();
        if (count > 0) {
            // 6、分页查询数据
            content = mongoTemplate.find(queryCriteria, SyncDataErrorLog.class);
        }
        return PageableExecutionUtils.getPage(content, pageable, () -> count);
    }

    @Override
    public void retrySyncData(String id) {
        // TODO:同步逻辑待实现
    }

    private Query createFindQuery(SyncDataLogQueryDto queryDto) {
        Query query = new Query();
        Criteria criteria = new Criteria();
        if (StringUtils.isNotBlank(queryDto.getCorporationCode())) {
            criteria.and("corporationCode").is(queryDto.getCorporationCode());
        }
        if (StringUtils.isNotEmpty(queryDto.getResponseCode())) {
            if (SUCC_CODE.equals(queryDto.getResponseCode())) {
                criteria.and("responseCode").is(queryDto.getResponseCode());
            } else {
                criteria.and("responseCode").ne(SUCC_CODE);
            }
        }
        query.addCriteria(criteria);
        return query;
    }

    @Override
    public List<CountSynDataListDto> countDailyData(Date updateTime) {

        List<CountSynDataListDto> resultList = new ArrayList<>();
        try {
            Query query = new Query().addCriteria(Criteria.where("updateTime").gte(updateTime));
            List<SynchronousData> synchronousDataList = mongoTemplate.find(query, SynchronousData.class);

            Map<String, List<SynchronousData>> collectMap = Optional.ofNullable(synchronousDataList).orElseGet(Lists::newArrayList)
                    .stream().collect(Collectors.groupingBy(SynchronousData::getSynchronousType));
            for (Map.Entry<String, List<SynchronousData>> entry : collectMap.entrySet()) {
                CountSynDataListDto countSynDataListDto = new CountSynDataListDto();

                int pullCount = entry.getValue().stream().mapToInt(SynchronousData::getPullCount).sum();
                int resolveCount = entry.getValue().stream().mapToInt(SynchronousData::getResolveCount).sum();
                int pullFailCount = entry.getValue().stream().mapToInt(SynchronousData::getPullFailCount).sum();
                int resolveFailCount = entry.getValue().stream().mapToInt(SynchronousData::getResolveFailCount).sum();

                //按类型统计
                countSynDataListDto.setSynchronousType(entry.getKey());
                countSynDataListDto.setPullCount(pullCount);
                countSynDataListDto.setResolveCount(resolveCount);
                countSynDataListDto.setPullFailCount(pullFailCount);
                countSynDataListDto.setResolveFailCount(resolveFailCount);
                resultList.add(countSynDataListDto);
            }
        } catch (Exception e) {
            log.error("统计每日同步数据异常:{}", e);
        }
        return resultList;
    }

    @Override
    public Page<SyncDataErrorLog> findByRetryIsTrue(int page, int size) {
        Pageable pageable = PageRequest.of((page - 1), size);
        return repository.findByRetryIsTrue(pageable);
    }

}
